package VectorApproach;

import java.util.ArrayList;

import XmlLoader.Position;

public class ClusterDistributionPool {
	
	public static final int STATE_HIGHT = 0;
	public static final int STATE_LOW = 1;
	
	ArrayList<Distribution> listDist = null;
	public LinearRegression lr = new LinearRegression();
	
	public ClusterDistributionPool() {
		this.listDist = new ArrayList<Distribution>();
	}
	
	public void ACT001_addEle(Distribution newDist) {
		ArrayList<Integer> list = newDist.GET001_listDistribution();
		while(list.size() > 1 && list.get(0) < 2 && list.get(1) < 2) {
			newDist.vecStart.startPos.x = newDist.vecStart.startPos.x + newDist.vecStart.eachVector.x;
			newDist.vecStart.startPos.y = newDist.vecStart.startPos.y + newDist.vecStart.eachVector.y;
			list.remove(0);
		}
		while(list.size() > 1 && list.get(list.size() - 1) < 2 && list.get(list.size() - 2) < 2) {
			list.remove(list.size() - 1);
		}
		newDist.ACT003_countImportance();
		if(newDist.GET003_importance() > 1) {
			this.listDist.add(newDist);
		}
	}
	
	public ArrayList<Position> ACT002_regression(int lineNum, int perSample, int cubeLen) {
		ArrayList<Position> listPos = new ArrayList<Position>();
		int curIndex = 0, indexNo = this.listDist.get(0).NoDist;
		double maxImport = 0;
		Distribution getMaxDist = null;
		ArrayList<Distribution> queDist = new ArrayList<Distribution>();
		
		double maxNum = 0, cutNum = 0;
		while(curIndex < this.listDist.size()) {
			Distribution getDist = this.listDist.get(curIndex);
			maxNum = getDist.GET008_max();
			//cutNum = cutHeightToMax * maxNum;
			
			/*
			int indexNum = 0;
			int preEndPos = -1;
			int curStartIndexHight = -1;
			int curState = ClusterDistributionPool.STATE_LOW;
			int[] curMaxPosRange = new int[2];
			curMaxPosRange[0] = 0;
			curMaxPosRange[1] = 0;
			
			while(indexNum < getDist.GET001_listDistribution().size()) {
				int getNum = getDist.GET001_listDistribution().get(indexNum);
				if(getNum >= cutNum) {
					if(curState == ClusterDistributionPool.STATE_LOW && preEndPos != -1) {  //low->hight
						if(indexNum - preEndPos > curMaxPosRange[1] - curMaxPosRange[0]) {  //update maximal range
							curMaxPosRange[0] = preEndPos;
							curMaxPosRange[1] = indexNum;
						}
						
					}
					curStartIndexHight = indexNum;
					curState = ClusterDistributionPool.STATE_HIGHT;
				}
				else {
					if(curState == ClusterDistributionPool.STATE_HIGHT) {  //height->low
						preEndPos = indexNum;
					}
					curState = ClusterDistributionPool.STATE_LOW;
				}
				indexNum = indexNum + 1;
			}
			
			int x = (curMaxPosRange[1] - curMaxPosRange[0] ) / 2;
			if(x == 0 && curStartIndexHight > 0) {
				x = curStartIndexHight;
			}
			
			Position pos = getDist.GET009_indexToPos(x);
			listPos.add(pos);
		    */
			if(indexNo == getDist.GET002_ID()[0] && getDist.GET003_importance() > 1) {
				int index = 0;
				boolean isAdd = false;
				while(!isAdd && index < queDist.size()) {
					if(getDist.GET003_importance() > queDist.get(index).GET003_importance()){
						queDist.add(index, getDist);
						isAdd = true;
					}
					index = index + 1;
				}
				if(!isAdd) {
					queDist.add(index, getDist);
				}
			}
			else {
				if(queDist.size() == 1) {
					listPos.add(queDist.get(0).GET006_medium());
				}
				else if(queDist.size() > 1) {
					Distribution d1, d2, temp;
					d1 = queDist.get(0);
					d2 = queDist.get(1);
					if(d1.segID > d2.segID) {
						temp = d1;
						d1 = d2;
						d2 = temp;
					}
					Position p1 = d1.GET005_right();
					p1.x = p1.x - 2;
					Position p2 = d2.GET004_left();
					listPos.add(p1);
				}
				queDist.clear();
				indexNo = getDist.GET002_ID()[0];
			}
			curIndex = curIndex + 1;
		}
		int index = 0;
		while(index < listPos.size()) {
			this.lr.ACT001_insertData((listPos.get(index).x * cubeLen), listPos.get(index).y * cubeLen);
			index = index + 1;
		}
		this.lr.ACT002_regression();
		return listPos;
	}
	
	public double ACT003_func(double x) {
		return this.lr.ACT003_func(x);
	}
	
	public double ACT004_revertFunc(double y) {
		return this.lr.ACT004_revertFunc(y);
	}
}
